//-------------------------------------------------------------------
//	Copyright (c) 2010-2012 Zhirnov Andrey
//	This file is part of the "UXGEN" project.
//	See copyright notice in "Engine.h".
//-------------------------------------------------------------------

#ifndef _UX_DEFAULT_PROGRAM_H
#define _UX_DEFAULT_PROGRAM_H

#include "../../../../Resources/Materials/CBaseProgramShell.h"

namespace Engine
{
namespace RenderUtils
{

	//
	// Default Program Shell interface
	//

	class _EXPORT_ IDefaultProgramShell : public CBaseProgramShell
	{
	private:
		virtual bool _Replace(CResource *pRes)						FINAL;
		virtual bool Link(IProgramMaterial *pMaterial)				FINAL;
		virtual bool GetLinkTextures(texture_array_t &aTextures)	FINAL;
		virtual bool _Load(IFilePtr pFile, uint uSize)				FINAL;
		virtual bool _Save(IFilePtr pFile)							FINAL;
		virtual bool _Reload(IFilePtr pFile, bool bRecursive)		FINAL;
		//virtual bool  AddConfigNode(static_obj_node_t pBaseNode)	FINAL;
		//virtual bool  AddConfigSaveNode(static_obj_node_t pBaseNode)FINAL;

		virtual e_resource::type	GetType()		 const		{ return e_resource::PROGRAM_SHELL; }
		virtual e_program::type		GetProgramType() const		{ return e_program::DIFFUSE; }
		
		virtual uint8 GetTextureStage(e_texture::type eType)	{ return eType == e_texture::DIFFUSE ? 0 : -1; }

	public:
		IDefaultProgramShell();

		virtual bool Copy(const CBaseProgramShellPtr &pProg) = 0;

		virtual void CombineMode(e_combine_mode::type eMode) = 0;
		virtual void AlphaTest(bool bEnable, float fAlphaRef = 0.5f) = 0;
		virtual void DiffuseColor(const color4f &sColor) = 0;
	};


	//
	// Default Program for Font
	//

	class _EXPORT_ CDefaultProgramFont : public IDefaultProgramShell
	{
	private:
		CShaderProgramPtr	_pShader;

	public:
		CDefaultProgramFont();
		~CDefaultProgramFont();

		bool Create(bool bUseGS, bool bColorOnly);
		virtual bool Copy(const CBaseProgramShellPtr &pProg);
		
		virtual void Bind();
		virtual void CombineMode(e_combine_mode::type eMode);
		virtual void AlphaTest(bool bEnable, float fAlphaRef = 0.5f);
		virtual void DiffuseColor(const color4f &sColor);
		
		virtual bool GetShaderProgram(CShaderProgramPtr &, e_shader::type);
	};



	//
	// Default Program for 2D
	//

	class _EXPORT_ CDefaultProgram2D : public IDefaultProgramShell
	{
	protected:
		STRUCT_ALIGN( 16 )
		struct TDefMtrParams
		{
			float		fAlphaRef;
			int			iCombineMode;
			int			iAlphaTest;
			///
			TDefMtrParams(): fAlphaRef(0.5f), iCombineMode(0), iAlphaTest(0) {}
		};
		
	protected:
		CShaderProgramPtr	_pShader;
		TDefMtrParams		_sParams;
		uint				_uMtrIndex;			// UBO with material

	public:
		CDefaultProgram2D();
		~CDefaultProgram2D();

		bool Create(bool bUseGS);
		virtual bool Copy(const CBaseProgramShellPtr &pProg);

		virtual void Bind();
		virtual void CombineMode(e_combine_mode::type eMode);
		virtual void AlphaTest(bool bEnable, float fAlphaRef = 0.5f);
		virtual void DiffuseColor(const color4f &sColor);
		
		virtual bool GetShaderProgram(CShaderProgramPtr &, e_shader::type);
	};



	//
	// Default Program for 3D
	//

	class _EXPORT_ CDefaultProgram3D : public IDefaultProgramShell
	{
	protected:
		STRUCT_ALIGN( 16 )
		struct TDefMtrParams
		{
			color4f		sDiffuseColor;
			float		fAlphaRef;
			int			iCombineMode;
			int			iAlphaTest;
			///
			TDefMtrParams(): fAlphaRef(0.5f), iCombineMode(0), iAlphaTest(0) {}
		};
		
	protected:
		CShaderProgramPtr	_pShader;
		TDefMtrParams		_sParams;
		uint				_uMtrIndex;

	public:
		CDefaultProgram3D();
		~CDefaultProgram3D();

		bool Create(bool bCubeMap);
		virtual bool Copy(const CBaseProgramShellPtr &pProg);
		
		virtual void Bind();
		virtual void CombineMode(e_combine_mode::type eMode);
		virtual void AlphaTest(bool bEnable, float fAlphaRef = 0.5f);
		virtual void DiffuseColor(const color4f &sColor);
		
		virtual bool GetShaderProgram(CShaderProgramPtr &, e_shader::type);
	};

//-------------------------------------------------------------------

}	// RenderUtils
}	// Engine

#endif	// _UX_DEFAULT_PROGRAM_H